﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace NeuralNetworks
{
    public partial class MainForm : Form
    {
        #region Private Members

        private NeuralNetwork _network;

        #endregion

        #region Constructors

        public MainForm()
        {
            this.InitializeComponent();

            this.InitializeNeuralNetwork(48, 7);

            _asciiControl.TrainingFinished += (sender, e) =>
                _drawPanel.Invalidate();
        }

        #endregion

        #region Private Methods

        private void InitializeNeuralNetwork(int inputLayerNeuronsCount, int outputLayerNeuronsCount)
        {
            var definition = new NeuralNetworkDefinition()
            {
                HiddenLayersCount = (int)_hiddenLayersCountTextBox.Value,
                HiddenLayersNeuronsCount = (int)_hiddenLayersNeuronsCountTextBox.Value,
                InputLayerNeuronsCount = inputLayerNeuronsCount,
                OutputLayerNeuronsCount = outputLayerNeuronsCount
            };

            _network = new NeuralNetwork(definition);
            _asciiControl.Network = _network;
            _orControl.Network = _network;
            Neuron.LearningRate = (float)_learningRateTextBox.Value;

            _drawPanel.Invalidate();
        }

        #endregion

        #region Signed Events Methods

        private void DrawPanel_Paint(object sender, PaintEventArgs e)
        {
            if (_network == null)
                return;

            _network.Draw(e.Graphics, e.ClipRectangle);
        }

        private void MainTabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            int inputLayerNeurons, outputLayerNeurons;
            if (_mainTabControl.SelectedTab == _orTabPage)
            {
                inputLayerNeurons = 2;
                outputLayerNeurons = 1;
            }
            else if (_mainTabControl.SelectedTab == _asciiTabPage)
            {
                inputLayerNeurons = 48;
                outputLayerNeurons = 7;
            }
            else
            {
                _network = null;
                return;
            }

            this.InitializeNeuralNetwork(inputLayerNeurons, outputLayerNeurons);
        }

        private void SaveNeuralNetworkButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveDialog = new SaveFileDialog();
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = saveDialog.FileName;
                File.WriteAllLines(filePath, _network.ToSerializableText());
            }
        }

        private void LoadNeuralNetwork_Click(object sender, EventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();
            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = openDialog.FileName;
                IEnumerable<string> lines = File.ReadAllLines(filePath);

                _network.Load(lines.ToArray());

                _drawPanel.Invalidate();
            }
        }

        #endregion
    }
}
